#include "MdParser.h"
#include <QDebug>
#include <QFile>
#include <QRegularExpression>
#include <QStringConverter>
#include <QTextStream>

MdParser::MdParser()
{
    qDebug() << "初始化MD解析器";
    m_maxLen = 3072; // 设置默认最大长度
    m_minLen = 1024; // 设置默认最小长度
}

MdParser::~MdParser() {}

bool MdParser::parse(const QString &content, int maxLen, int minLen)
{
    m_maxLen = maxLen;
    m_minLen = minLen;

    // 将文本分割成初始段落
    QList<QString> initialParagraphs = splitIntoParagraphs(content);
    qDebug() << "初始分段完成，共" << initialParagraphs.size() << "个段落";

    // 处理段落长度
    QList<QString> processedParagraphs = processParagraphs(initialParagraphs);
    qDebug() << "段落处理完成，最终共" << processedParagraphs.size() << "个段落";

    qDebug() << "段落处理完成，详细信息:";
    for (int i = 0; i < processedParagraphs.size(); ++i) {
        qDebug() << "段落" << i + 1 << ":";
        qDebug() << "内容:" << processedParagraphs[i].left(100) + "..."; // 只显示前100个字符
        qDebug() << "长度:" << processedParagraphs[i].length();
        qDebug() << "----------------";
    }

    // 将处理后的段落保存到m_mdInfoList
    m_mdInfoList.clear();
    for (const QString &paragraph : processedParagraphs)
    {
        MdInfo info;
        info.content = paragraph;
        m_mdInfoList.append(info);
    }

    qDebug() << "成功解析MD文件，共" << m_mdInfoList.size() << "个段落";
    return true;
}

bool MdParser::parse(const QString &filePath)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
    {
        qDebug() << "无法打开MD文件:" << filePath;
        return false;
    }

    QTextStream in(&file);
    in.setEncoding(QStringConverter::Utf8);

    // 读取整个文件内容
    QString content = in.readAll();
    file.close();

    // qDebug() << "原始内容:" << content;

    return parse(content, m_maxLen, m_minLen);;
}

QList<QString> MdParser::splitIntoParagraphs(const QString &content)
{
    qDebug() << "开始分段处理...";
    qDebug() << "原始内容长度:" << content.length();

    // 第一步：按标题分段
    qDebug() << "\n=== 第一步：按标题分段 ===";
    QList<QString> titleParagraphs = splitByTitles(content);
    qDebug() << "按标题分段结果:" << titleParagraphs.size() << "个段落";
    for (int i = 0; i < titleParagraphs.size(); ++i) {
        qDebug() << "段落" << i + 1 << "长度:" << titleParagraphs[i].length();
        qDebug() << "内容:" << titleParagraphs[i].left(100) + "..."; // 只显示前100个字符
        if (titleParagraphs[i].length() > m_maxLen) {
            qDebug() << "段落" << i + 1 << "超过最大长度限制";
        }
        qDebug() << "----------------";
    }

    // 检查是否所有段落都符合长度要求
    if (isAllParagraphsValid(titleParagraphs)) {
        qDebug() << "按标题分段后所有段落都符合长度要求，结束分段";
        return titleParagraphs;
    }

    // 第二步：对超长段落按句号分段
    qDebug() << "\n=== 第二步：按句号分段 ===";
    QList<QString> sentenceParagraphs = splitBySentences(titleParagraphs);
    qDebug() << "按句号分段结果:" << sentenceParagraphs.size() << "个段落";
    for (int i = 0; i < sentenceParagraphs.size(); ++i) {
        qDebug() << "段落" << i + 1 << "长度:" << sentenceParagraphs[i].length();
        qDebug() << "内容:" << sentenceParagraphs[i].left(100) + "..."; // 只显示前100个字符
        if (sentenceParagraphs[i].length() > m_maxLen) {
            qDebug() << "段落" << i + 1 << "超过最大长度限制";
        }
        qDebug() << "----------------";
    }
    
    if (isAllParagraphsValid(sentenceParagraphs)) {
        qDebug() << "按句号分段后所有段落都符合长度要求，结束分段";
        return sentenceParagraphs;
    }

    // 第三步：对超长段落按空行分段
    qDebug() << "\n=== 第三步：按空行分段 ===";
    QList<QString> blankLineParagraphs = splitByBlankLines(sentenceParagraphs);
    qDebug() << "按空行分段结果:" << blankLineParagraphs.size() << "个段落";
    for (int i = 0; i < blankLineParagraphs.size(); ++i) {
        qDebug() << "段落" << i + 1 << "长度:" << blankLineParagraphs[i].length();
        qDebug() << "内容:" << blankLineParagraphs[i].left(100) + "..."; // 只显示前100个字符
        if (blankLineParagraphs[i].length() > m_maxLen) {
            qDebug() << "段落" << i + 1 << "超过最大长度限制";
        }
        qDebug() << "----------------";
    }
    
    if (isAllParagraphsValid(blankLineParagraphs)) {
        qDebug() << "按空行分段后所有段落都符合长度要求，结束分段";
        return blankLineParagraphs;
    }

    // 第四步：最后按换行符分段
    qDebug() << "\n=== 第四步：按换行符分段 ===";
    QList<QString> result = splitByNewlines(blankLineParagraphs);
    qDebug() << "按换行符分段结果:" << result.size() << "个段落";
    for (int i = 0; i < result.size(); ++i) {
        qDebug() << "段落" << i + 1 << "长度:" << result[i].length();
        if (result[i].length() > m_maxLen) {
            qDebug() << "警告：段落" << i + 1 << "仍然超过最大长度限制";
        }
    }

    qDebug() << "分段处理完成";
    return result;
}

// 辅助函数：检查所有段落是否都符合长度要求
bool MdParser::isAllParagraphsValid(const QList<QString> &paragraphs)
{
    bool valid = true;
    for (const QString &para : paragraphs) {
        if (para.length() > m_maxLen) {
            qDebug() << "发现超长段落，长度:" << para.length() << "，超出限制:" 
                     << (para.length() - m_maxLen) << "字符";
            valid = false;
        }
    }
    return valid;
}

// 按标题分段
QList<QString> MdParser::splitByTitles(const QString &content)
{
    QList<QString> paragraphs;
    QRegularExpression titleRegex(R"(^#{1,6}\s+.*$)", QRegularExpression::MultilineOption);
    QStringList lines = content.split('\n');
    
    QString currentParagraph;
    bool inCodeBlock = false;
    
    for (const QString &line : lines) {
        // 处理代码块标记
        if (line.trimmed().startsWith("```")) {
            inCodeBlock = !inCodeBlock;
            currentParagraph += line + "\n";
            continue;
        }
        
        // 在代码块内，直接添加行
        if (inCodeBlock) {
            currentParagraph += line + "\n";
            continue;
        }
        
        // 检查是否是标题行
        if (titleRegex.match(line).hasMatch()) {
            if (!currentParagraph.isEmpty()) {
                paragraphs.append(currentParagraph);
            }
            currentParagraph = line + "\n";
        } else {
            currentParagraph += line + "\n";
        }
    }
    
    if (!currentParagraph.isEmpty()) {
        paragraphs.append(currentParagraph);
    }
    
    return paragraphs;
}

// 按空行分段
QList<QString> MdParser::splitByBlankLines(const QList<QString> &paragraphs)
{
    QList<QString> result;
    
    for (const QString &para : paragraphs) {
        if (para.length() <= m_maxLen) {
            result.append(para);
            continue;
        }
        
        QStringList lines = para.split('\n');
        QString currentParagraph;
        bool inCodeBlock = false;
        bool lastLineWasEmpty = false;  // 跟踪上一行是否为空行
        
        for (const QString &line : lines) {
            // 处理代码块
            if (line.trimmed().startsWith("```")) {
                inCodeBlock = !inCodeBlock;
                currentParagraph += line + "\n";
                lastLineWasEmpty = false;
                continue;
            }
            
            if (inCodeBlock) {
                currentParagraph += line + "\n";
                lastLineWasEmpty = false;
                continue;
            }
            
            // 空行处理
            if (line.trimmed().isEmpty()) {
                currentParagraph += line + "\n";  // 保留空行
                if (!lastLineWasEmpty) {  // 只在第一个空行时分段
                    if (!currentParagraph.isEmpty()) {
                        result.append(currentParagraph);
                        currentParagraph.clear();
                    }
                }
                lastLineWasEmpty = true;
            } else {
                currentParagraph += line + "\n";
                lastLineWasEmpty = false;
            }
        }
        
        if (!currentParagraph.isEmpty()) {
            result.append(currentParagraph);
        }
    }
    
    return result;
}

// 按句号分段
QList<QString> MdParser::splitBySentences(const QList<QString> &paragraphs)
{
    QList<QString> result;
    
    for (const QString &para : paragraphs) {
        if (para.length() <= m_maxLen) {
            result.append(para);
            continue;
        }
        
        QStringList lines = para.split('\n');
        QString currentParagraph;
        bool inCodeBlock = false;
        
        for (int i = 0; i < lines.size(); ++i) {
            const QString &line = lines[i];
            
            // 处理代码块
            if (line.trimmed().startsWith("```")) {
                inCodeBlock = !inCodeBlock;
                currentParagraph += line + "\n";
                continue;
            }
            
            if (inCodeBlock) {
                currentParagraph += line + "\n";
                continue;
            }
            
            // 安全检查下一行的索引
            bool isLastLine = (i >= lines.size() - 1);
            bool hasNextEmptyLine = false;
            
            // 只有当不是最后一行时才检查下一行
            if (!isLastLine && i + 1 < lines.size()) {
                hasNextEmptyLine = lines[i + 1].trimmed().isEmpty();
            }
            
            // 检查句号并且下一行为空行
            if ((line.trimmed().endsWith("。") || line.trimmed().endsWith(".")) && hasNextEmptyLine) {
                currentParagraph += line + "\n";
                if (i + 1 < lines.size()) {
                    currentParagraph += lines[i + 1] + "\n";  // 保留空行
                    i++;  // 跳过已添加的空行
                }
                result.append(currentParagraph);
                currentParagraph.clear();
            } else {
                currentParagraph += line + "\n";
            }
        }
        
        if (!currentParagraph.isEmpty()) {
            result.append(currentParagraph);
        }
    }
    
    return result;
}

// 按换行符分段
QList<QString> MdParser::splitByNewlines(const QList<QString> &paragraphs)
{
    QList<QString> result;
    
    for (const QString &para : paragraphs) {
        if (para.length() <= m_maxLen) {
            result.append(para);
            continue;
        }
        
        QStringList lines = para.split('\n');
        QString currentParagraph;
        bool inCodeBlock = false;
        QString codeBlockStart; // 保存代码块的开始标记
        
        for (const QString &line : lines) {
            // 处理代码块开始
            if (line.trimmed().startsWith("```")) {
                if (!inCodeBlock) {
                    // 进入代码块
                    inCodeBlock = true;
                    codeBlockStart = line; // 保存代码块开始标记
                    
                    // 如果当前段落不为空且接近最大长度，先保存当前段落
                    if (!currentParagraph.isEmpty()) {
                        result.append(currentParagraph);
                        currentParagraph = codeBlockStart + "\n";
                    } else {
                        currentParagraph = line + "\n";
                    }
                } else {
                    // 退出代码块
                    inCodeBlock = false;
                    currentParagraph += line + "\n";
                    result.append(currentParagraph);
                    currentParagraph.clear();
                }
                continue;
            }
            
            // 在代码块内的处理
            if (inCodeBlock) {
                // 检查添加当前行是否会超过最大长度
                if (currentParagraph.length() + line.length() + 5 > m_maxLen) { // +5 为结束标记```的长度
                    // 在当前段落末尾添加代码块结束标记
                    currentParagraph += "```\n";
                    result.append(currentParagraph);
                    // 新段落以代码块开始标记开头
                    currentParagraph = codeBlockStart + "\n" + line + "\n";
                } else {
                    currentParagraph += line + "\n";
                }
                continue;
            }
            
            // 非代码块内的处理
            if (currentParagraph.length() + line.length() + 1 > m_maxLen) {
                if (!currentParagraph.isEmpty()) {
                    result.append(currentParagraph);
                }
                currentParagraph = line + "\n";
            } else {
                currentParagraph += line + "\n";
            }
        }
        
        // 处理最后一个段落
        if (!currentParagraph.isEmpty()) {
            // 如果在代码块内结束，确保添加结束标记
            if (inCodeBlock) {
                currentParagraph += "```\n";
            }
            result.append(currentParagraph);
        }
    }
    
    return result;
}

QList<QString> MdParser::processParagraphs(const QList<QString> &paragraphs)
{
    QList<QString> processedParagraphs;
    QString currentParagraph;

    for (const QString &paragraph : paragraphs)
    {
        // 如果当前段落为空，直接赋值并继续下一个段落
        if (currentParagraph.isEmpty()) {
            currentParagraph = paragraph;
            continue;
        }

        // 计算当前段落与新段落合并后的总长度
        int combinedLength = currentParagraph.length() + paragraph.length();

        // 情况1: 合并后长度不超过最大限制，可以考虑合并
        if (combinedLength <= m_maxLen)
        {
            // 若当前段落已达到最小长度要求，可以独立保存
            if (currentParagraph.length() >= m_minLen)
            {
                processedParagraphs.append(currentParagraph);
                currentParagraph = paragraph; // 开始新段落
            }
            else // 当前段落未达到最小长度，需要合并
            {
                currentParagraph += paragraph;
            }
        }
        // 情况2: 合并会超过最大长度限制
        else
        {
            // 若当前段落已达到最小长度要求
            if (currentParagraph.length() >= m_minLen)
            {
                // 直接保存当前段落，开始新段落
                processedParagraphs.append(currentParagraph);
                currentParagraph = paragraph;
            }
            else // 当前段落未达到最小长度
            {
                // 特殊情况：新段落本身就超过最大长度限制
                if (paragraph.length() > m_maxLen)
                {
                    // 处理当前累积的段落
                    if (!currentParagraph.isEmpty()) {
                        // 如果当前段落长度超过100字符，认为有足够的内容可以独立保存
                        if (currentParagraph.length() > 100) {
                            // 分别保存当前段落和新段落
                            processedParagraphs.append(currentParagraph);
                            processedParagraphs.append(paragraph);
                        }
                        else {
                            // 当前段落内容太少(<=100字符)，强制与新段落合并后保存
                            // 注意：这可能导致段落超过最大长度限制，但优先保证内容完整性
                            currentParagraph += paragraph;
                            processedParagraphs.append(currentParagraph);
                        }
                        // 清空当前段落，准备处理后续内容
                        currentParagraph.clear();
                    }
                    else {
                        // 当前没有累积的段落，直接保存新段落
                        processedParagraphs.append(paragraph);
                    }
                }
                else // 新段落未超过最大长度
                {
                    // 虽然当前段落小于最小长度，但由于无法安全合并，
                    // 仍然保存当前段落并开始新段落
                    processedParagraphs.append(currentParagraph);
                    currentParagraph = paragraph;
                }
            }
        }
    }

    // 处理最后一个累积的段落
    if (!currentParagraph.isEmpty())
    {
        processedParagraphs.append(currentParagraph);
    }

    return processedParagraphs;
}

bool MdParser::save(const QString &filePath, const QVector<MdInfo> &mdInfoList)
{
    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
    {
        qDebug() << "无法创建MD文件:" << filePath;
        return false;
    }

    QTextStream out(&file);
    out.setEncoding(QStringConverter::Utf8);

    for (const MdInfo &info : mdInfoList)
    {
        // 写入翻译内容，如果没有则写入原文
        if (!info.translateContent.isEmpty())
        {
            out << info.translateContent;
        }
        else
        {
            out << info.content;
        }
    }

    file.close();
    qDebug() << "成功保存MD文件:" << filePath;

    // // 读取保存的文件，验证内容

    // QFile file_read(filePath);
    // if (!file_read.open(QIODevice::ReadOnly | QIODevice::Text))
    // {
    //     qDebug() << "无法打开MD文件:" << filePath;
    //     return false;
    // }

    // QTextStream in(&file_read);
    // in.setEncoding(QStringConverter::Utf8);

    // // 读取整个文件内容
    // QString content = in.readAll();
    // file_read.close();

    // qDebug() << "保存内容:" << content;

    return true;
}